## Sid Meier's Civilization 4
## Copyright Firaxis Games 2005
##
## Partisan by GIR
##

from CvPythonExtensions import *
import CvUtil
import PyHelpers
import Popup as PyPopup

# globals
gc = CyGlobalContext()
PyPlayer = PyHelpers.PyPlayer
PyInfo = PyHelpers.PyInfo


########################################################################################################################################

class adPartisan:

	def doCityAcquired(self, argsList):
		owner,playerType,city,bConquest,bTrade = argsList

#################################
### - create partisan units - ###
#################################

		### number of Partisan units depending on city size (before conquest) and if  ###
		### the loser of the city is stronger or weaker (military power) as the new   ###
		###                          owner of the city.                               ###
		###---------------------------------------------------------------------------###
		###  city size  | Partisan Units if | Partisan Units if   | reduce population ###
		### before conq.| loser weaker conq.| loser stronger conq.|                   ###
		###-------------+-------------------+---------------------+-------------------###
		###    01-07    |       1 - 2       |       0 - 1         |         0         ###
		###    08-14    |       2 - 3       |       1 - 2         |  - num partisans  ###
		###    15-21    |       3 - 5       |       1 - 3         |  - num partisans  ###
		###    22-28    |       4 - 6       |       2 - 4         |  - num partisans  ###
		###    29-35    |       5 - 8       |       2 - 5         |  - num partisans  ###
		###    36-42    |       6 - 9       |       3 - 6         |  - num partisans  ###
		###     ...     |        ...        |        ...          |  - num partisans  ###
		###-------------+-------------------+---------------------+-------------------###
		###             |  +3 units with    |  +3 units with      |                   ###
		###             |  NATIONHOOD civic |  NATIONHOOD civic   |                   ###


		###      new created Partisan units will get more and more promotions with higher       ###
		###      tech level and also get special promotions dependig on the "start" plot        ###
		###-------------------------------------------------------------------------------------###
		###     technology      |     plot types      |      promotions      |      chance      ###
		###---------------------+---------------------+----------------------+------------------###
		###      rifling        |          you need rifling tech to get Partisan units          ###
		###    assembly line    |          -          |       + drill        |       100%       ###
		###    industrialism    |          -          |       + drill        |       100%       ###
		###      rocketry       |          -          |       + drill        |       100%       ###
		###      plastics       |          -          |       + drill        |       100%       ###
		###      computers      |          -          |       + drill        |       100%       ###
		###     combustion      |          -          |     + flanking I     |       100%       ###
		###      refining       |          -          |     + flanking II    |       100%       ###
		###       radio         |          -          |     + flanking III   |        50%       ###
		###      fascism        |          -          |       + combat       |        50%       ###
		###         -           |   forest / jungle   |     + woodsman I     |       100%       ###
		###    assembly line    |   forest / jungle   |     + woodsman II    |        75%       ###
		###    industrialism    |   forest / jungle   |     + woodsman III   |        50%       ###
		###         -           |        hill         |     + guerilla I     |       100%       ###
		###    assembly line    |        hill         |     + guerilla II    |        75%       ###
		###    industrialism    |        hill         |     + guerilla III   |        50%       ###
		###         -           |       desert        |  + desert combat I   |       100%       ###
		###    assembly line    |       desert        |  + desert combat II  |        75%       ###
		###         -           |    tundra / snow    |  + arctic combat I   |       100%       ###
		###    assembly line    |    tundra / snow    |  + arctic combat II  |        75%       ###

		if bConquest:
			loserPlayer = gc.getPlayer(owner)
			loserPlayerTeam = loserPlayer.getTeam()
	### partisans only available with rifling tech ###
			if ( gc.getTeam(loserPlayerTeam).isHasTech(gc.getInfoTypeForString("TECH_RIFLING")) == true ):
	### dont place partisan units if you capture your city back ###
				if ( city.isOccupation()==true ):
	### dont show partisan message if loserPlayer is already death ###
					if ( loserPlayer.isAlive()==true ):

						u_partisan = gc.getInfoTypeForString( 'UNIT_PARTISAN' )		
						loserTeam = gc.getTeam(owner)
						loserPlayerID = loserPlayer.getID()
						lPnCities = loserPlayer.getNumCities()
						conqTeam = gc.getTeam(city.getOwner())
						conqPlayer = gc.getPlayer(city.getOwner())
						conqPlayerID = conqPlayer.getID()
						iX = city.getX()
						iY = city.getY()
						cityName = city.getName()
						tt_noterrain = gc.getInfoTypeForString( 'NO_TERRAIN' )
						tt_coast = gc.getInfoTypeForString( 'TERRAIN_COAST' )
						tt_ocean = gc.getInfoTypeForString( 'TERRAIN_OCEAN' )
						tt_desert = gc.getInfoTypeForString( 'TERRAIN_DESERT' )
						tt_tundra = gc.getInfoTypeForString( 'TERRAIN_TUNDRA' )
						tt_snow = gc.getInfoTypeForString( 'TERRAIN_SNOW' )
						ft_ice = gc.getInfoTypeForString('FEATURE_ICE')
						ft_forest = gc.getInfoTypeForString('FEATURE_FOREST')
						ft_jungle = gc.getInfoTypeForString( 'FEATURE_JUNGLE' )
						it_fort = gc.getInfoTypeForString("IMPROVEMENT_FORT") 
						t_rocketry = gc.getInfoTypeForString("TECH_ROCKETRY")
						t_plastics = gc.getInfoTypeForString("TECH_PLASTICS")
						t_assemblyline = gc.getInfoTypeForString("TECH_ASSEMBLY_LINE")
						t_industrialism = gc.getInfoTypeForString("TECH_INDUSTRIALISM")
						t_computers = gc.getInfoTypeForString("TECH_COMPUTERS")
						t_combustion = gc.getInfoTypeForString("TECH_COMBUSTION")
						t_refining = gc.getInfoTypeForString("TECH_REFINING")
						t_radio = gc.getInfoTypeForString("TECH_RADIO")
						t_fascism = gc.getInfoTypeForString("TECH_FASCISM")
						p_drill1 = gc.getInfoTypeForString( "PROMOTION_DRILL1" )
						p_drill2 = gc.getInfoTypeForString( "PROMOTION_DRILL2" )
						p_drill3 = gc.getInfoTypeForString( "PROMOTION_DRILL3" )
						p_drill4 = gc.getInfoTypeForString( "PROMOTION_DRILL4" )
						p_drill5 = gc.getInfoTypeForString( "PROMOTION_DRILL5" )
						p_flanking1 = gc.getInfoTypeForString( 'PROMOTION_FLANKING1' )
						p_flanking2 = gc.getInfoTypeForString( 'PROMOTION_FLANKING2' )
						p_flanking3 = gc.getInfoTypeForString( 'PROMOTION_FLANKING3' )
						p_combat1 = gc.getInfoTypeForString("PROMOTION_COMBAT1")
						p_combat2 = gc.getInfoTypeForString("PROMOTION_COMBAT2")
						p_woodsman1 = gc.getInfoTypeForString("PROMOTION_WOODSMAN1")
						p_guerilla1 = gc.getInfoTypeForString("PROMOTION_GUERILLA1")
						p_warmth1 = gc.getInfoTypeForString("PROMOTION_WARMTH1")
						p_cold1 = gc.getInfoTypeForString("PROMOTION_COLD1")
						i_inner_plot = -1
						l_inner_plot = [0,0,0,0,0,0,1,1,1,0,0,1,1,1,0,0,1,1,1,0,0,0,0,0,0]
						lpPlots = []
						drilltech = 0
						count_Partisan = 0
						damage = 0

	### more/fewer partisans if the loser is weaker/stronger (power) - also depending on city size ###
						citysize = city.getPopulation()
						nPartisan = (citysize / 7) + 1
	### +3 partisans with nationhood civic ###
						if ( citysize >= 6 ):
							if ( loserPlayer.getCivics(gc.getInfoTypeForString('CIVICOPTION_LEGAL'))==gc.getInfoTypeForString('CIVIC_NATIONHOOD') ):
								nPartisan += 3

			### random number (between 1 and 3*) depending on city size (begin) ###
						rel_ativ = 1
						if ( citysize > 14 ):
							rel_ativ = 2
						if ( citysize > 28 ):
							rel_ativ = 3
						iRand = CyGame().getSorenRandNum( rel_ativ, "Random which pPlot for Partisan")
						rel_ativ = iRand + 1
			### random number (between 1 and 3*) depending on city size (end) ###

			### add/take away the random number from the nPartisan (depending on power) ###
						if ( loserPlayer.getPower() > conqPlayer.getPower() ):
							iRand = CyGame().getSorenRandNum( 10, "Random which pPlot for Partisan")
							### 40% chance for more units ###
							if ( iRand < 6 ):
								nPartisan -= rel_ativ
						elif ( loserPlayer.getPower() < conqPlayer.getPower() ):
							iRand = CyGame().getSorenRandNum( 10, "Random which pPlot for Partisan")
							### 40% chance for more units ###
							if ( iRand >= 6 ):
								nPartisan += rel_ativ

	### check all city radius plots ###
						for iXLoop in range(iX - 2, iX + 3, 1):
							for iYLoop in range(iY - 2, iY + 3, 1):
								i_inner_plot += 1
								pPlot = CyMap().plot(iXLoop, iYLoop)
								if ( pPlot.getTerrainType()!=tt_noterrain and pPlot.getTerrainType()!=tt_coast and pPlot.getTerrainType()!=tt_ocean and pPlot.getFeatureType()!=ft_ice and pPlot.isPeak()==false ):
									if ( pPlot.isCity()==false ):
										if ( pPlot.isVisibleEnemyUnit(loserPlayerID)==false ):
											lpPlots.append(pPlot)
			### doubles the chance to set the partisan in the inner city radius ###
											if ( l_inner_plot[i_inner_plot] == 1 ):
												lpPlots.append(pPlot)
					### increase the chance to set the partisan in the inner city radius with certain extras ###
												if ( pPlot.getFeatureType()==ft_forest or pPlot.getFeatureType()==ft_jungle or pPlot.isHills()==true or pPlot.getImprovementType()==it_fort ):
													for i in range(4):
														lpPlots.append(pPlot)
	### set partisan(s) ###
						if ( len(lpPlots) > 0 ):
							while ( nPartisan > 0 ):
								nPartisan -= 1
								count_Partisan += 1
								iRand = CyGame().getSorenRandNum( len(lpPlots), "Random which pPlot for Partisan")
								pPlot = lpPlots[iRand]
								iiX = pPlot.getX()
								iiY = pPlot.getY()
								pNewUnit = loserPlayer.initUnit( u_partisan, iiX, iiY, UnitAITypes.UNITAI_ATTACK_CITY )
		### set aditional promotions ###
				### tech lvl depending promotions ###
						### DRILL promotions ###
								if ( gc.getTeam(loserPlayerTeam).isHasTech(t_assemblyline) == true ):
									drilltech += 1
								if ( gc.getTeam(loserPlayerTeam).isHasTech(t_industrialism) == true ):
									drilltech += 1
								if ( gc.getTeam(loserPlayerTeam).isHasTech(t_rocketry) == true ):
									drilltech += 1
								if ( gc.getTeam(loserPlayerTeam).isHasTech(t_plastics) == true ):
									drilltech += 1
								if ( gc.getTeam(loserPlayerTeam).isHasTech(t_computers) == true ):
									drilltech += 1
								while ( drilltech > 0 ):
									drilltech -= 1
									if ( pNewUnit.isHasPromotion(p_drill1)==false ):
										pNewUnit.setHasPromotion(p_drill1, true)
									elif ( pNewUnit.isHasPromotion(p_drill2)==false ):
										pNewUnit.setHasPromotion(p_drill2, true)
									elif ( pNewUnit.isHasPromotion(p_drill3)==false ):
										pNewUnit.setHasPromotion(p_drill3, true)
									elif ( pNewUnit.isHasPromotion(p_drill4)==false ):
										pNewUnit.setHasPromotion(p_drill4, true)
									elif ( pNewUnit.isHasPromotion(p_drill5)==false ):
										pNewUnit.setHasPromotion(p_drill5, true)
						### FLANKING promotions ###
								if ( gc.getTeam(loserPlayerTeam).isHasTech(t_combustion) == true ):
									pNewUnit.setHasPromotion(p_flanking1, true)
								if ( gc.getTeam(loserPlayerTeam).isHasTech(t_refining) == true ):
									pNewUnit.setHasPromotion(p_flanking2, true)
								if ( gc.getTeam(loserPlayerTeam).isHasTech(t_radio) == true ):
									chance = CyGame().getSorenRandNum( 2, "Random Flanking III")
									if ( chance == 0 ):
										pNewUnit.setHasPromotion(p_flanking3, true)
						### COMBAT promotion ###
								if ( gc.getTeam(loserPlayerTeam).isHasTech(t_fascism) == true ):
									chance = CyGame().getSorenRandNum( 2, "Random Combat1/2")
									if ( chance == 0 ):
										if ( pNewUnit.isHasPromotion(p_combat1)==false ):
											pNewUnit.setHasPromotion(p_combat1, true)
										elif ( pNewUnit.isHasPromotion(p_combat1)==true ):
											pNewUnit.setHasPromotion(p_combat2, true)
				### plot type depending promotions ###
						### WOODSMAN promotion ###
								if ( pPlot.getFeatureType()==ft_forest or pPlot.getFeatureType()==ft_jungle ):
									pNewUnit.setHasPromotion(p_woodsman1, true)
									chance = CyGame().getSorenRandNum( 4, "Random Woodsman2")
									if ( chance >= 1 ):
										if ( gc.getTeam(loserPlayerTeam).isHasTech(t_assemblyline) == true ):
											pNewUnit.setHasPromotion(gc.getInfoTypeForString("PROMOTION_WOODSMAN2"), true)
											chance = CyGame().getSorenRandNum( 4, "Random Woodsman3")
											if ( chance >= 1 ):
												if ( gc.getTeam(loserPlayerTeam).isHasTech(t_industrialism) == true ):
													pNewUnit.setHasPromotion(gc.getInfoTypeForString("PROMOTION_WOODSMAN3"), true)
						### DESERT COMBAT promotion ###
								if ( pPlot.getTerrainType()==tt_desert ):
									pNewUnit.setHasPromotion(p_warmth1, true)
									chance = CyGame().getSorenRandNum( 4, "Random DesertCombat2")
									if ( chance >= 1 ):
										if ( gc.getTeam(loserPlayerTeam).isHasTech(t_assemblyline) == true ):
											pNewUnit.setHasPromotion(gc.getInfoTypeForString("PROMOTION_WARMTH2"), true)
						### ARCTIC COMBAT promotion ###
								if ( pPlot.getTerrainType()==tt_tundra or pPlot.getTerrainType()==tt_snow ):
									pNewUnit.setHasPromotion(p_cold1, true)
									chance = CyGame().getSorenRandNum( 4, "Random ArcticCombat2")
									if ( chance >= 1 ):
										if ( gc.getTeam(loserPlayerTeam).isHasTech(t_assemblyline) == true ):
											pNewUnit.setHasPromotion(gc.getInfoTypeForString("PROMOTION_COLD2"), true)
						### GUERILLA promotion ###
								if ( pPlot.isHills()==true ):
									pNewUnit.setHasPromotion(p_guerilla1, true)
									chance = CyGame().getSorenRandNum( 4, "Random Guerilla2")
									if ( chance >= 1 ):
										if ( gc.getTeam(loserPlayerTeam).isHasTech(t_assemblyline) == true ):
											pNewUnit.setHasPromotion(gc.getInfoTypeForString("PROMOTION_GUERILLA2"), true)
											chance = CyGame().getSorenRandNum( 4, "Random Guerilla3")
											if ( chance >= 1 ):
												if ( gc.getTeam(loserPlayerTeam).isHasTech(t_industrialism) == true ):
													pNewUnit.setHasPromotion(gc.getInfoTypeForString("PROMOTION_GUERILLA3"), true)

		### set random damage to random enemy units near the partisan unit ###
							### remember all EnemyUnits near the partisan ###
								lEnemyUnits = []
								for iiXLoop in range(iiX - 1, iiX + 2, 1):
									for iiYLoop in range(iiY - 1, iiY + 2, 1):
										ppPlot = CyMap().plot(iiXLoop, iiYLoop)
										if ( ppPlot.isVisibleEnemyUnit(loserPlayerID)==true ):
											for i in range(ppPlot.getNumUnits()):
												if ( ppPlot.isVisibleEnemyUnit(loserPlayerID)==true ):
													ppUnit = ppPlot.getUnit(i)
													lEnemyUnits.append(ppUnit)
								if ( len(lEnemyUnits) > 0 ):
							### random number between 1 and 5 (but not more than EnemyUnits near the partisan unit) ###
									n_EnemyUnits = len(lEnemyUnits)
									if n_EnemyUnits >= 5:
										n_EnemyUnits = 5
									n_EnemyUnits = CyGame().getSorenRandNum( n_EnemyUnits, "Random for how many eunits will suffer damage") + 1
							### choose which EnemyUnit will suffer damage from partisan unit ###
									while ( n_EnemyUnits > 0 ):
										n_EnemyUnits -= 1
										iRand = CyGame().getSorenRandNum( len(lEnemyUnits), "Random which eunit will suffer damage")
										ppUnit = lEnemyUnits[iRand]
									### random for how many damage the eunit will suffer from the partisan attack (15 - 30) ###
										iRand = CyGame().getSorenRandNum( 16, "rand damage") + 15
									### check to not kill the eunit ###
										if ( (ppUnit.getDamage() + iRand) >= 99 ):
											if ( ppUnit.getDamage() <= 98 ):
												iRand = (iRand - ((ppUnit.getDamage() + iRand) - 100))
											else:
												iRand = 0
											ppUnit.setDamage(99, 0)
										else:
											ppUnit.changeDamage(iRand, 0)
										damage = damage + (ppUnit.baseCombatStr() * (iRand * 0.01))
	### ausgabe ###
										i_iX = ppUnit.getX()
										i_iY = ppUnit.getY()
										CyInterface().addMessage(loserPlayerID,True,5,'','',1,'Art/Interface/Buttons/actions/destroy.dds',ColorTypes(11), i_iX, i_iY, True,True)
										CyInterface().addMessage(conqPlayerID,True,5,'','',1,'Art/Interface/Buttons/actions/destroy.dds',ColorTypes(7), i_iX, i_iY, True,True)
								if ( lPnCities > 0 ):
									CyInterface().addMessage(loserPlayerID,True,25,'','',1,'Art/Interface/Buttons/Units/marine.dds',ColorTypes(11), iiX, iiY, True,True)
									CyInterface().addMessage(conqPlayerID,True,25,'','',1,'Art/Interface/Buttons/Units/marine.dds',ColorTypes(7), iiX, iiY, True,True)
							if ( lPnCities > 0 ):
								CyInterface().addMessage(loserPlayerID,true,15,' Our Brave People near %s will Fight against the Enemy! They already caused a total of %d Damage to the Evil Enemy Force. ' %(cityName,damage),'',0,'Art/Interface/Buttons/civics/despotism.dds',ColorTypes(44), iX, iY, True,True)
								CyInterface().addMessage(conqPlayerID,true,15,' Partisans and Terrorists near %s Fight against our Brave Army! They already caused a total of %d Damage to our Glorious Force. ' %(cityName,damage),'',0,'Art/Interface/Buttons/civics/despotism.dds',ColorTypes(7), iX, iY, True,True)
	### reduce population ###
							if ( lPnCities > 0 ):
								if ( citysize > 8 ):
									city.changePopulation(-count_Partisan)



